# Makefile for VCS UVM Compile Flow
# Usage:
#  make sim                -> Compile Verilog/SV and link with UVM
#  make run TEST=test_name -> Run the specified test (e.g., make run TEST=test_mode0)
#  make wave TEST=test_name -> Run with waveform generation
#  make clean              -> Cleanup

export PROJECT_PATH

# Tools
VHDLAN      := vhdlan
VLOGAN      := vlogan
VCS         := vcs

# VHDL compilation arguments
VHDL_ARGS   := -full64 -nc -work work

# Verilog/SystemVerilog compilation arguments
VLOG_ARGS   := -full64 -sverilog +v2k +lint=all,noSVA -timescale=1ns/1ps -work work \
               +incdir+${PROJECT_PATH}/include \
               +incdir+${PROJECT_PATH}/design/aru \
               +incdir+$(VCS_HOME)/etc/uvm/src

# VCS linking arguments
# -debug_acc+all is the recommended debug option
# -kdb: Enable Verdi KDB (Knowledge Database) for better type awareness
# -lca: Line coverage analysis
# -CFLAGS -DVCS: Pass VCS define to C compiler
# UVM DPI library is required for UVM functions
VCS_ARGS    := -full64 -debug_acc+all -kdb \
               $(VCS_HOME)/etc/uvm/src/dpi/uvm_dpi.cc \
               -CFLAGS -DVCS 

SIMV        := ./simv
FILELIST    := filelist.f
VHDL_FLIST  := vhdl_files.f
TOP         := tb_top
TEST        ?= test_mode0  # Default test to run if not specified


.PHONY: all sim run wave clean

all: sim

# Step 1: Compile VHDL files using vhdlan
compile_vhdl:
	@echo "=== Step 1: Compiling VHDL files with vhdlan ==="
	$(VHDLAN) $(VHDL_ARGS) -f $(VHDL_FLIST) -l vhdlan.log
	@echo "=== VHDL compilation finished ==="

# Step 2: Compile Verilog/SystemVerilog files using vlogan
compile_vlog: compile_vhdl
	@echo "=== Step 2: Compiling Verilog/SystemVerilog with vlogan ==="
	$(VLOGAN) $(VLOG_ARGS) -f $(FILELIST) -l vlogan.log
	@echo "=== Verilog compilation finished ==="

# Step 3: Link using vcs
sim: compile_vlog
	@echo "=== Step 3: Linking with VCS ==="
	$(VCS) $(VCS_ARGS) -top $(TOP) -o $(SIMV) -l vcs.log || (echo "=== Build failed, see vcs.log ==="; exit 1)
	@echo "=== Build finished: $(SIMV) created ==="

# Run sim 
run: sim
	@if [ ! -f $(SIMV) ]; then \
		echo "Error: simv not found. Please run 'make sim' first."; \
		exit 1; \
	fi
	@echo "=== Running test: $(TEST) ==="
	$(SIMV) +UVM_TESTNAME=$(TEST) +ntb_random_seed=auto +UVM_VERBOSITY=UVM_HIGH

# Open waveform with Verdi
verdi: run
	@if [ ! -f $(TOP).fsdb ]; then \
		echo "Error: $(TOP).fsdb not found. Please run 'make wave' first."; \
		exit 1; \
	fi
	@echo "=== Opening Verdi with $(TOP).fsdb ==="
	verdi -ssf $(TOP).fsdb -sv -f $(FILELIST) -top $(TOP)

# Debug: run test and open Verdi automatically
debug:
	@echo "=== Running test with waveform and opening Verdi ==="
	$(MAKE) wave TEST=$(TEST)
	@sleep 2
	$(MAKE) verdi

clean:
	@echo "=== Cleaning ==="
	rm -rf simv csrc ucli.key DVEfiles AN.DB work *.log *.fsdb vcs.key verdiLog novas*
